<script setup>
import { ref, watch } from 'vue';
import { useToast } from 'primevue/usetoast';
import Dialog from 'primevue/dialog';
import FileUpload from 'primevue/fileupload';
import Button from 'primevue/button';
import axios from 'axios';
import { useAdminStore } from '@/store/admin';

const adminStore = useAdminStore();
const toast = useToast();

// 接收父组件传递的参数
const props = defineProps({
    visible: {
        type: Boolean,
        required: true
    }
});

// 定义事件
const emit = defineEmits(['update:visible', 'confirm']);

// 数据状态
const previewImage = ref(''); // 预览图
const selectedFile = ref(null); // 选中的文件
const uploadedUrl = ref(''); // 上传后的图片 URL

// 监听 visible 变化
watch(
    () => props.visible,
    (newVal) => {
        if (!newVal) {
            resetDialog(); // 关闭时重置对话框
        }
    }
);

// 处理 visible 变化
const onVisibleChange = (value) => {
    emit('update:visible', value); // 触发 update:visible 事件
};

// 选择图片
const onSelectImage = ({ files }) => {
    const file = files[0];
    if (!file) return;

    // 生成预览图
    const reader = new FileReader();
    reader.onload = (e) => {
        previewImage.value = e.target.result;
    };
    reader.readAsDataURL(file);

    selectedFile.value = file;
    uploadImage();
};

// 上传图片
const uploadImage = async () => {
    if (!selectedFile.value) return;

    const formData = new FormData();
    formData.append('file', selectedFile.value);

    try {
        const config = {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        };

        // 添加鉴权令牌
        if (adminStore.token) {
            config.headers.Authorization = `Bearer ${adminStore.token}`;
        }
        const response = await axios.post('/api/v1/backend/upload/picture', formData, config);
        // console.log(response);
        // 更新图片 URL
        uploadedUrl.value = response.data.data.url;

        toast.add({
            severity: 'success',
            summary: '上传成功',
            detail: '图片已上传',
            life: 3000
        });
    } catch (error) {
        toast.add({
            severity: 'error',
            summary: '上传失败',
            detail: error.message,
            life: 3000
        });
    }
};

// 确认上传
const confirmUpload = () => {
    if (uploadedUrl.value) {
        emit('confirm', uploadedUrl.value); // 返回上传结果
        emit('update:visible', false); // 关闭对话框
    }
};

// 关闭对话框
const closeDialog = () => {
    emit('update:visible', false); // 关闭对话框
};

// 重置对话框
const resetDialog = () => {
    previewImage.value = '';
    selectedFile.value = null;
    uploadedUrl.value = '';
};

// 错误处理
const onUploadError = (error) => {
    let message = '文件上传错误';
    if (error.message.includes('maxFileSize')) {
        message = '文件大小不能超过1MB';
    } else if (error.message.includes('accept')) {
        message = '仅支持图片格式';
    }
    toast.add({
        severity: 'error',
        summary: '错误',
        detail: message,
        life: 3000
    });
};
</script>

<template>
    <Dialog :visible="visible" @update:visible="onVisibleChange" header="上传图片" :modal="true" :style="{ width: '500px' }">
        <!-- 图片上传组件 -->
        <div class="upload-container">
            <FileUpload mode="basic" name="image" :auto="true" :customUpload="true" :multiple="false" :maxFileSize="1024000" accept="image/*" chooseLabel="选择图片" @select="onSelectImage" @error="onUploadError" />

            <!-- 图片预览 -->
            <div v-if="previewImage" class="preview-container">
                <img :src="previewImage" alt="预览图片" class="preview-image" />
            </div>
        </div>

        <!-- 底部按钮 -->
        <template #footer>
            <Button label="取消" icon="pi pi-times" @click="closeDialog" class="p-button-text" />
            <Button label="确定" icon="pi pi-check" @click="confirmUpload" :disabled="!uploadedUrl" />
        </template>
    </Dialog>
</template>

<style scoped>
.upload-container {
    text-align: center;
}

.preview-container {
    margin-top: 1rem;
}

.preview-image {
    max-width: 100%;
    max-height: 200px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
</style>
